package cn.sh.tools.service.component.mail;

import cn.hutool.cache.Cache;
import cn.hutool.cache.impl.FIFOCache;
import cn.hutool.core.util.StrUtil;
import cn.sh.tools.domain.constant.CommonConstant;
import cn.sh.tools.util.file.FileUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * @author shihao
 * @description 邮件
 */
@Component
@Slf4j
public class MailComponent {

    @Resource
    private JavaMailSender javaMailSenderImpl;

    /**
     * 邮件发送者
     */
    @Value("${spring.mail.username}")
    private String from;

    private static final String comma = ",";

    private static final String tos = "tos";
    private static final String ccs = "ccs";

    private Cache<String, String[]> mailInfoMap;

    /**
     * 发送邮件
     *
     * @param to      收件人
     * @param cc      抄送人
     * @param subject 邮件主题
     * @param content 邮件内容
     */
    public String sendSimpleMail(String[] to, String[] cc,
                                 String subject, String content) {
        if (!StrUtil.equalsIgnoreCase(this.mailInfoMap.get(CommonConstant.ENABLE)[0], "true")) {
            log.info("没有开启发送邮件的服务");
            return "没有开启发送邮件的服务";
        }

        SimpleMailMessage smm = new SimpleMailMessage();
        // 邮件发送者
        smm.setFrom(this.from);
        // 收件人
        if (null != to && to.length > 0) {
            smm.setTo(to);
        } else {
            smm.setTo(this.mailInfoMap.get(tos));
        }
        // 抄送人
        if (null != cc && cc.length > 0) {
            smm.setTo(cc);
        } else {
            smm.setCc(this.mailInfoMap.get(ccs));
        }
        smm.setSubject(subject);
        smm.setText(content);

        try {
            this.javaMailSenderImpl.send(smm);

            return "邮件发送成功";
        } catch (MailException e) {
            log.error("邮件发送异常", e);
            return "邮件发送异常";
        }
    }

    @PostConstruct
    public void init() {
//        List<String> contentList = this.readMailFile();
        List<String> contentList = FileUtils.readFileFromClasspath(CommonConstant.MAIL_INFO, StandardCharsets.UTF_8);

        if (null != mailInfoMap) {
            this.mailInfoMap.clear();
        }

        this.mailInfoMap = new FIFOCache<>(contentList.size());

        contentList.forEach(line -> {
            String key = line.substring(0, line.indexOf(CommonConstant.EQUAL_SIGN));
            String value = line.substring(line.indexOf(CommonConstant.EQUAL_SIGN) + 1);

            if (value.contains(comma)) {
                String[] values = value.split(comma, -1);
                mailInfoMap.put(key, values);
            } else {
                mailInfoMap.put(key, new String[]{value});
            }
        });
        log.info("邮件准备信息已完成");
    }

    /**
     * 读取 mailInfo.dd 文件内容
     */
    private List<String> readMailFile() {
        ClassPathResource classPathResource = new ClassPathResource(CommonConstant.MAIL_INFO);

        List<String> contentList;
        String errorMsg = "读取mailInfo.dd文件异常";
        try {
            InputStream inputStream = classPathResource.getInputStream();
            contentList = IOUtils.readLines(inputStream, StandardCharsets.UTF_8.name());

            if (null == contentList || contentList.isEmpty()) {
                throw new RuntimeException("文件mailInfo.dd内容不能为空");
            }

            return contentList;
        } catch (IOException e) {
            log.error(errorMsg, e);
            throw new RuntimeException(e.getMessage());
        }
    }

}
